var fs = require("fs");
var express = require("express");
var crypto = require("crypto");
var Db = require("mongodb").Db;
var Server = require("mongodb").Server;
var PostProvider = require("./post_provider").PostProvider;
var UserProvider = require("./user_provider").UserProvider;

fs.readFile("conf.json", function(err, data) {
  var conf = JSON.parse(data);
  
  var server = express.createServer();
  server.configure(function() {
    server.set("views", __dirname + "/views");
    server.set("view engine", "jade");
    //server.use(require('stylus').middleware({ src: __dirname + '/public' }));
    server.use(express.bodyParser());
    server.use(express.static(__dirname + '/public'));
    server.use(express.cookieParser());
    server.use(express.session({ secret: "lady baba" }));
  });
  
  var db_connector = new Db('babatag-db', new Server(conf.dbHost, conf.dbPort, {auto_reconnect: true}, {}));
  
  db_connector.open(function(err, db){
    var posts = new PostProvider(db);
    var users = new UserProvider(db);

    server.get("/", function(req, res) {
      posts.findAll(function(err, data) {
        res.render("view_posts.jade", {locals:{title:"All posts", posts:data, user:req.session.user}});
      });
    });

    server.get("/posts", function(req, res) {
      posts.findAll(function(err, data) {
        res.render("view_posts.jade", {locals:{title:"All posts", posts:data, user:req.session.user}});
      });
    });

    server.get("/newpost", function(req, res) {
      if (!req.session.user) { res.redirect("/login"); return; }
      res.render("new_post.jade", {locals:{title:"New post", user:req.session.user}});
    });

    server.post("/newpost", function(req, res) {
      if (!req.session.user) { res.send(403); return; }
      var author = req.session.user;
      var title = req.param("title");
      var body = req.param("body");
      var tags = req.param("tags").split(/\s*\,\s*/);
      posts.insert(author, title, body, null, tags, function(err, data) {
        res.redirect("/");
      });
    });

    server.get("/newuser", function(req, res) {
      res.render("new_user.jade", {locals:{title:"New user", user:req.session.user}});
    });

    server.post("/newuser", function(req, res) {
      req.session.user = undefined;
      var userid = req.param("userid");
      var hash = crypto.createHash("sha1");
      hash.update(req.param("passwd"));
      users.insert(userid, hash.digest("hex"), function(err, data) {
        res.redirect("/");
      });
    });

    server.get("/login", function(req, res) {
      req.session.user = undefined;
      res.render("login.jade", {locals:{title:"User login", user:req.session.user}});
    });

    server.post("/login", function(req, res) {
      var userid = req.param("userid");
      var hash = crypto.createHash("sha1");
      hash.update(req.param("passwd"));
      users.authenticate(userid, hash.digest("hex"), function(err, data) {
        if (err != null || data == null) res.redirect("/login");
        else {
          req.session.user = data._id;
          res.redirect("/");
        }
      });
    });

    server.get("/logout", function(req, res) {
      req.session.user = undefined;
      res.redirect("/");
    });

    server.get("/posts/:id", function(req, res) {
      posts.findById(req.params.id, function(err, data) {
        res.render("view_posts.jade", {locals:{title:data.title, posts:data, user:req.session.user}});
      });
    });

    server.post("/posts/:id/like", function(req, res) {
      if (!req.session.user) { res.send(403); return; }
      posts.like(req.session.user, req.params.id, function(err, data) {
        posts.findById(req.params.id, function(err, data) {
          res.writeHead(200, {"Content-Type":"text/plain"});
          res.write((data.likes.length - data.dislikes.length).toString());
          res.end();
        });
      });
    });

   server.post("/posts/:id/dislike", function(req, res) {
      if (!req.session.user) { res.send(403); return; }
      posts.dislike(req.session.user, req.params.id, function(err, data) {
        posts.findById(req.params.id, function(err, data) {
          res.writeHead(200, {"Content-Type":"text/plain"});
          res.write((data.likes.length - data.dislikes.length).toString());
          res.end();
        });
      });
    });

    server.get("/topics/:id", function (req, res) {
      posts.findTopic(req.params.id, function (err, data) {
        res.render("view_posts.jade", {locals:{title:"Topic - "+data[0].title, posts:data, user:req.session.user}});
      });
    });

    server.get("/topics/:id/reply", function(req, res) {
      if (!req.session.user) { res.redirect("/login"); return; }
      posts.findById(req.params.id, function (err, data) {
        res.render("new_post.jade", {locals:{title:"Reply to topic - "+data.title, user:req.session.user}});
      });
    });

    server.post("/topics/:id/reply", function(req, res) {
      if (!req.session.user) { res.send(403); return; }
      var author = req.session.user;
      var title = req.param("title");
      var body = req.param("body");
      var tags = req.param("tags").split(/\s*\,\s*/);
      var reply_to = req.params.id
      posts.insert(author, title, body, reply_to, tags, function(err, data) {
        res.redirect("/");
      });
    });

    server.get("/tags", function(req, res) {
      posts.topTags(function(err, data) {
        res.render("top_tags.jade", {locals:{title:"Trending tags", tags:data, user:req.session.user}});
      });
    });

    server.get("/tags/:tag", function(req, res) {
      posts.findByTag(req.params.tag, function(err, data) {
        res.render("view_posts.jade", {locals:{title:"#"+req.params.tag, posts:data, user:req.session.user}});
      });
    });
  });
  
  server.listen(conf.serverPort);
  process.setuid(conf.uid);
});
